/*
 练习文件操作和浮点数操作
 precision配置与说明https://www.cplusplus.com/reference/ios/ios_base/precision/
 setf说明:https://www.cplusplus.com/reference/ios/ios_base/setf/?kw=setf
 主要练习ostream setf, width, precision

 fmtflags setf (fmtflags fmtfl) 设置的是fmtfl，其它的不变
 fmtflags setf (fmtflags fmtfl, fmtflags mask); 设置的是fmtfl和mask的并集，同时清楚mask单独包含的
 
 可以设置的fmtflags可以参考：https://www.cplusplus.com/reference/ios/ios_base/fmtflags/
 Both return the value of the stream's format flags before the call.
*/
#include <iostream>
#include <fstream>
#include <cstdlib>

void testFormatFlag(void);
void testWidth(void);
void testPrecision(void);
using namespace std;
void fileIt(ofstream &of, double array[], int num);

int main_filefunct () {
    // testFormatFlag();
    // testWidth();
    // testPrecision();
    // 打开文件，如果没有的话创建一个
    
    ofstream os;
    const char *fileName = "area.txt";
    // 在没有文件的情况下会自动创建一个
    os.open(fileName);
    if (!os.is_open())
    {
        cout << "File open faild ..." << endl;
        exit(EXIT_FAILURE);
        return 1;
    }
    const int num = 4;
    double radius[num];
    cout << "Please input " << num << " radiuses to calculate area..." << endl;
    // 输入四个半径的值
    for (size_t i = 0; i < num; i++)
    {
        cout << "Please input " << (i + 1) << " radius." << endl;
        cin >> radius[i];
    }
    // 计算四个面积的值，并且存入文件中
    fileIt(os, radius, num);

    return 0;
}

void testFormatFlag(void) {
 
  std::cout.setf( std::ios::boolalpha );
  std::cout << true << std::endl;
  std::cout.unsetf( std::ios::boolalpha);
  std::cout << true << std::endl;
  /*
  输出结果
  true
  1
  */
  //设置以十六进制的形式展示
  using namespace std;
  cout.setf(ios::hex, ios::basefield);
  cout.setf(ios::showbase);
  cout << 100 << endl;
  cout.unsetf(ios::showbase);
  cout << 100 << endl;
  /*
  输出结果
  0x64
  64
  */
}

void testWidth(void) {
    using namespace std;
    cout << "1234567890" << endl; 
    // 设置输出内容的宽度，默认是按照右侧对齐
    cout.width(10);
    cout << 12.03 << endl;
    cout.width(20);
    cout << 1234.5 << endl;
}

void testPrecision(void) {
    const double f = 3.14159;
    using namespace std;
    cout.precision(5);
    cout << f << endl;
    cout.precision(10);
    cout << f << endl;
    cout.setf(ios::fixed, ios::floatfield);
    cout << f << endl;
    /*
    输出：
    3.1416
    3.14159
    3.1415900000
    说明precision设置的是生效的数字个数，同时如果不设置floatfied，那么其默认只输出该输出的最大值
    */
}

void fileIt(std::ofstream &of,double array[], int num) {
    using namespace std;
    of << "The calculated result is:" << endl;
    ios_base::fmtflags initflags;
    // 调用完成之后返回的是未调用之前的配置
    // 设置成 定点小数: https://blog.csdn.net/ruidianbaihuo/article/details/87884720
    initflags = of.setf(ios_base::fixed);
    of.setf(ios::showpoint);
    of.precision(4);
    for (int i = 0; i < num; i ++)
    {
        of.width(12);
        of << array[i];
        of.width(15);
        of << (3.1415926 *  array[i] *  array[i]) << endl;
    }
    of.setf(initflags);
}


